from wiki import app
from wiki.databases import WikiPostDB, UserDB, QueueWikiPostDB, db
from wiki.utils import nocache, login_required, convert_size, redirect_back, ISO639, allowed_file, edit_wiki, add_wiki
from flask import Blueprint, render_template, request, flash, redirect, url_for, session, abort
from psutil import cpu_percent, cpu_count, virtual_memory, disk_usage
from flask_babel import gettext
from bs4 import BeautifulSoup
from werkzeug import secure_filename
from platform import machine
from json import loads, dumps
from time import strftime
from re import sub
from os.path import join, isfile, abspath, dirname

admin = Blueprint('admin', __name__)

@admin.route('/')
@nocache
@login_required(status=True, privilege='admin')
def index():
	users_num = len(UserDB.query.all())
	wiki_posts_num = len(WikiPostDB.query.all())
	admins = UserDB.query.filter_by(privilege='admin').all()
	queue_posts_num = len(QueueWikiPostDB.query.all())
	return render_template('admin/index.html', queue_posts_num=queue_posts_num,
	                       users_num=users_num, wiki_posts_num=wiki_posts_num, cpu_percent=cpu_percent,
	                       cpu_count=cpu_count, machine=machine,
	                       virtual_memory=virtual_memory, convert_size=convert_size,
	                       disk_usage=disk_usage, admins=admins)

@admin.route('/wiki/add/')
@nocache
@login_required(status=True, privilege='admin')
def add_post():
	return render_template('admin/add_post.html')

@admin.route('/wiki/posts/')
@nocache
@login_required(status=True, privilege='admin')
def posts():
	query = WikiPostDB.query.all()
	return render_template('admin/posts.html', query=query)

@admin.route('/wiki/queue-posts/')
@nocache
@login_required(status=True, privilege='admin')
def queue_posts():
	query = QueueWikiPostDB.query.all()
	return render_template('admin/queue_posts.html', query=query)

@admin.route('/wiki/posts/config', methods=['POST'])
@nocache
@login_required(status=True, privilege='admin')
def posts_config():
	if request.method == 'POST':
		if request.form['submit'] == 'add':
			url = sub('[/?]', '', sub('[ +]', '-', request.form['post-header']))
			url = url[:-1] if url.endswith('-') else url
			return add_wiki(url=url, address=request.form['post-header'],
				            content=request.form['content'], redirect_url=url_for('admin.posts'),
				            error_redirect=url_for('admin.add_post'), privilege=session['current_user']['privilege'],
				            lang=request.form['language'][0:2].lower())
		elif request.form['submit'] == 'edit':
			url = sub('[/?]', '', sub('[ +]', '-', request.form['post-header']))
			url = url[:-1] if url.endswith('-') else url
			return edit_wiki(Id=request.form['id'], url=url,
				             address=request.form['post-header'], content=request.form['content'],
				             redirect_url=url_for('admin.posts'), error_redirect=url_for('admin.posts'),
				             privilege=session['current_user']['privilege'], lang=request.form['language'][0:2].lower())
		else:
			return abort(404)
	else:
		return abort(404)

@admin.route('/wiki/posts/delete', methods=['GET'])
@nocache
@login_required(status=True, privilege='admin')
def delete_post():
	if request.method == 'GET':
		query = WikiPostDB.query.filter_by(Id=request.args.get('id'), default_lang=request.args.get('language')).first_or_404()
		db.session.delete(query)
		db.session.commit()
		return redirect(url_for('admin.posts'))
	else:
		return abort(404)

@admin.route('/wiki/queue-posts/config', methods=['POST'])
@nocache
@login_required(status=True, privilege='admin')
def queue_config():
	if request.method == 'POST':
		if session['current_user']['privilege'] == 'admin':
			query = QueueWikiPostDB.query.filter_by(Id=request.form['id']).first_or_404()
			if request.form['submit'] == gettext('Delete'):
				db.session.delete(query)
				db.session.commit()
				return redirect_back()
			elif request.form['submit'] == gettext('Publish') or request.form['submit'] == gettext('Merge'):
				creator = UserDB.query.filter_by(Id=query.creator_id).first_or_404().username
				if query.orginal_id.isdigit():
					newQuery = WikiPostDB.query.filter_by(Id=int(query.orginal_id), default_lang=query.default_lang).first_or_404()
					newQuery.content = str(query.content)
					newQuery.address = query.address
					newQuery.change_history = loads(newQuery.change_history)
					newQuery.change_history.append(gettext('Edited by') + ' <a href="/'+ session['lang'].lower()\
					                              +'/user/{}">{}</a>'.format(creator, creator) +  gettext(' at ')\
					                              + strftime(gettext('%Y-%m-%d %H-%M-%S')))
					newQuery.change_history = dumps(newQuery.change_history)
					newQuery.url = query.url
					db.session.delete(query)
					db.session.commit()
				else:
					if len(WikiPostDB.query.filter_by(url=query.url).all()) >= 1:
						flash('Error')
						return redirect_back()
					newQuery = WikiPostDB(content=str(query.content), url=query.url,
										  address=query.address, change_history=query.change_history,
										  creator_id=query.creator_id, default_lang=query.default_lang)
					db.session.delete(query)
					db.session.add(newQuery)
					db.session.commit()
				return redirect_back()
			elif request.form['submit'] == gettext('Save'):
				soup = BeautifulSoup(request.form['content'], 'html.parser')
				for header in soup.findAll(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']):
					header['id'] = header.text
				query.content = str(soup)
				db.session.commit()
				return redirect_back()
			else:
				return abort(404)
		else:
			return abort(403)
	else:
		return abort(404)

@admin.route('/users/')
@nocache
@login_required(status=True, privilege='admin')
def users():
	query = UserDB.query.all()
	return render_template('admin/users.html', query=query)

@admin.route('/users/config', methods=['GET'])
@nocache
@login_required(status=True, privilege='admin')
def users_config():
	if request.method == 'GET':
		query = UserDB.query.filter_by(Id=request.args.get('id')).first_or_404()
		if request.args.get('submit') == gettext('Delete'):
			db.session.delete(query)
			db.session.commit()
		elif request.args.get('submit') == gettext('Promote'):
			query.privilege = 'admin'
			db.session.commit()
		elif request.args.get('submit') == gettext('Demote'):
			query.privilege = 'user'
			db.session.commit()
		else:
			return abort(404)
		return redirect_back()
	else:
		return abort(404)

@admin.route('/settings/')
@nocache
@login_required(status=True, privilege='admin')
def settings():
	return render_template('admin/settings.html', iso=ISO639)

@admin.route('/settings/config', methods=['POST'])
@nocache
@login_required(status=True, privilege='admin')
def settings_config():
	try:
		if request.method == 'POST':
			FAVICON = request.files['FAVICON']
			WEBSITE_LOGO = request.files['WEBSITE_LOGO']
			if not isfile(app.config['UPLOAD_FOLDER']+request.form['favicon-text']):
				if FAVICON and allowed_file(request.form['favicon-text'].split('/')[-1]):
					if request.form['favicon-text'] == '':
						flash('Error')
						return redirect(url_for('admin.settings'))
					else:
						FAVICON.save(join(app.config['UPLOAD_FOLDER']+'images', 
										secure_filename(request.form['favicon-text'].split('/')[-1])))
				else:
					flash('Error')
					return redirect(url_for('admin.settings'))
			if not isfile(app.config['UPLOAD_FOLDER']+request.form['logo-text']):
				if WEBSITE_LOGO and allowed_file(request.form['logo-text'].split('/')[-1]):
					if request.form['logo-text'] == '':
						flash('Error')
						return redirect(url_for('admin.settings'))
					else:
						WEBSITE_LOGO.save(join(app.config['UPLOAD_FOLDER']+'images', 
											secure_filename(request.form['logo-text'].split('/')[-1])))
				else:
					flash('Error')
					return redirect(url_for('admin.settings'))

			if request.form['DEFAULT_LANGUAGE'] not in ISO639:
					flash('LangError')
					return redirect(url_for('admin.settings'))
			with open(join(dirname(dirname(dirname(abspath(__file__)))), 'config.py'), 'r') as file:
				data = file.readlines()
				for i in range(0, len(data)):
					if data[i].startswith('WEBSITE_LOGO'):
						data[i] = "WEBSITE_LOGO = gettext('{}')\n".format('images/'+ \
							request.form['logo-text'].split('/')[-1].replace(' ', '_'))
					elif data[i].startswith('FAVICON'):
						data[i] = "FAVICON = '{}'\n".format('images/'+request.form['favicon-text'].split('/')[-1].replace(' ', '_'))
					elif data[i].startswith('WEBSITE_NAME'):
						data[i] = "WEBSITE_NAME = gettext('{}')\n".format(request.form['WEBSITE_NAME'])
					elif data[i].startswith('FOOTER_MESSAGE'):
						data[i] = "FOOTER_MESSAGE = gettext('{}')\n".format(request.form['FOOTER_MESSAGE'])
					elif data[i].startswith('DEFAULT_LANGUAGE'):
						data[i] = "DEFAULT_LANGUAGE = '{}'\n".format(request.form['DEFAULT_LANGUAGE'].upper())
				with open(join(dirname(dirname(dirname(abspath(__file__)))), 'config.py'), 'w') as file:
				    file.writelines(data)
			flash('Success')
			return redirect(url_for('admin.settings'))
		else:
			return abort(404)
	except Exception:
		return abort(404)